home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland Pascal with Objects 7.0 / PXWIN.ZIP / PXACCESS.PAS next >
Encoding:
Pascal/Delphi Source File  |  1992-10-27  |  6.5 KB  |  281 lines

  1. {************************************************}
  2. {                                                }
  3. {   Paradox Engine demo access unit              }
  4. {   Copyright (c) 1992 by Borland International  }
  5. {                                                }
  6. {************************************************}
  7.  
  8. { Note: This demo requires version 3.0 of the Paradox Engine. }
  9.  
  10. unit PXAccess;
  11.  
  12. interface
  13.  
  14. {$N+}
  15.  
  16. uses Objects, PXEngWin;
  17.  
  18. type
  19.   PFieldArray = ^TFieldArray;
  20.   TFieldArray = array[1..256] of PChar;
  21.  
  22. type
  23.   PPXTable = ^TPXTable;
  24.   TPXTable = object(TObject)
  25.     Status: Integer;
  26.     constructor Init(TableName: PChar);
  27.     destructor Done; virtual;
  28.     procedure ClearError;
  29.     function FieldName(Field: Integer): PChar;
  30.     function FieldType(Field: Integer): PChar;
  31.     function FieldWidth(Field: Integer): Integer;
  32.     function GetField(Rec, Fld: Integer): PChar;
  33.     function NumRecords: LongInt;
  34.     function NumFields: Integer;
  35.     procedure PXError(Error: Integer); virtual;
  36.   private
  37.     CurRecord: Integer;
  38.     TblHandle: TableHandle;
  39.     RecHandle: RecordHandle;
  40.     NumFlds: Integer;
  41.     NumRecs: LongInt;
  42.     FieldNames: PFieldArray;
  43.     FieldTypes: PFieldArray;
  44.     Cache: Pointer;
  45.     function CheckError(Code: Integer): Boolean;
  46.   end;
  47.  
  48. implementation
  49.  
  50. uses WinTypes, WinProcs, Strings, PXMsg;
  51.  
  52. type
  53.   PCache = ^TCache;
  54.   TCache = object(TCollection)
  55.     constructor Init(CacheSize: Integer);
  56.     procedure Add(Index: LongInt; P: PChar);
  57.     function Get(Index: LongInt): PChar;
  58.     procedure FreeItem(P: Pointer); virtual;
  59.   end;
  60.  
  61. type
  62.   PCacheElement = ^TCacheElement;
  63.   TCacheElement = record
  64.     Index: LongInt;
  65.     Item: PChar;
  66.   end;
  67.  
  68. constructor TCache.Init(CacheSize: Integer);
  69. begin
  70.   TCollection.Init(CacheSize, 0);
  71. end;
  72.  
  73. procedure TCache.Add(Index: LongInt; P: PChar);
  74. var
  75.   CE: PCacheElement;
  76. begin
  77.   New(CE);
  78.   CE^.Index := Index;
  79.   CE^.Item := P;
  80.   if Count = Limit then AtFree(Count - 1);
  81.   AtInsert(0, CE);
  82. end;
  83.  
  84. function TCache.Get(Index: LongInt): PChar;
  85. var
  86.   P: PCacheElement;
  87.  
  88.   function ItemWithIndex(P: PCacheElement): Boolean; far;
  89.   begin
  90.     ItemWithIndex := P^.Index = Index;
  91.   end;
  92.  
  93. begin
  94.   Get := nil;
  95.   P := FirstThat(@ItemWithIndex);
  96.   if P <> nil then Get := P^.Item;
  97. end;
  98.  
  99. procedure TCache.FreeItem(P: Pointer);
  100. begin
  101.   StrDispose(PCacheElement(P)^.Item);
  102.   Dispose(P);
  103. end;
  104.  
  105. { TPXTable }
  106.  
  107. constructor TPXTable.Init(TableName: PChar);
  108. var
  109.   Temp: array[0..25] of Char;
  110.   I: Integer;
  111. begin
  112.   FieldTypes := nil;
  113.   FieldNames := nil;
  114.   Status := 0;
  115.   CurRecord := -1;
  116.   if CheckError(PXTblOpen(TableName, TblHandle, 0, True)) and
  117.      CheckError(PXRecBufOpen(TblHandle, RecHandle)) and
  118.      CheckError(PXRecBufOpen(tblHandle, recHandle)) and
  119.      CheckError(PXRecNFlds(tblHandle, NumFlds)) and
  120.      CheckError(PXTblNRecs(tblHandle, NumRecs)) then
  121.   begin
  122.     GetMem(FieldTypes, NumFields * SizeOf(PChar));
  123.     GetMem(FieldNames, NumFields * SizeOf(PChar));
  124.     for I := 1 to NumFields do
  125.     begin
  126.       CheckError(PXFldName(TblHandle, I, SizeOf(Temp), Temp));
  127.       FieldNames^[I] := StrNew(Temp);
  128.       CheckError(PXFldType(TblHandle, I, SizeOf(Temp), Temp));
  129.       FieldTypes^[I] := StrNew(Temp);
  130.     end;
  131.     Cache := New(PCache, Init(300));
  132.   end;
  133. end;
  134.  
  135. destructor TPXTable.Done;
  136. var
  137.   I: Integer;
  138. begin
  139.   PXRecBufClose(RecHandle);
  140.   PXTblClose(TblHandle);
  141.   if (FieldTypes <> nil) and (FieldNames <> nil) then
  142.     for I := 1 to NumFields do
  143.     begin
  144.       StrDispose(FieldNames^[I]);
  145.       StrDispose(FieldTypes^[I]);
  146.     end;
  147.   if FieldTypes <> nil then FreeMem(FieldTypes, NumFields * SizeOf(PChar));
  148.   if FieldNames <> nil then FreeMem(FieldNames, NumFields * SizeOf(PChar));
  149.   if Cache <> nil then Dispose(PCache(Cache), Done);
  150.   TObject.Done;
  151. end;
  152.  
  153. function TPXTable.CheckError(Code: Integer): Boolean;
  154. begin
  155.   if Status = 0 then
  156.   begin
  157.     if Code <> 0 then PXError(Code);
  158.     Status := Code;
  159.   end;
  160.   CheckError := Status = 0;
  161. end;
  162.  
  163. procedure TPXTable.ClearError;
  164. begin
  165.   Status := 0;
  166. end;
  167.  
  168. function TPXTable.FieldName(Field: Integer): PChar;
  169. begin
  170.   FieldName := FieldNames^[Field];
  171. end;
  172.  
  173. function TPXTable.FieldType(Field: Integer): PChar;
  174. begin
  175.   FieldType := FieldTypes^[Field];
  176. end;
  177.  
  178. function TPXTable.FieldWidth(Field: Integer): Integer;
  179. var
  180.   Width, Code: Integer;
  181. begin
  182.   case FieldTypes^[Field][0] of
  183.     'N',
  184.     '$': FieldWidth := 14;
  185.     'A':
  186.       begin
  187.     Val(PChar(@FieldTypes^[Field][1]), Width, Code);
  188.     FieldWidth := Width
  189.       end;
  190.     'D': FieldWidth := 12;
  191.     'S': FieldWidth := 8;
  192.   else
  193.     FieldWidth := 0;
  194.   end;
  195. end;
  196.  
  197. function TPXTable.GetField(Rec, Fld: Integer): PChar;
  198. const
  199.   TheData: array[0..255] of Char = '';
  200. var
  201.   Tmp: array[0..255] of Char;
  202.   N: Double;
  203.   I: Integer;
  204.   L: LongInt;
  205.   ArgList: array[0..2] of Integer;
  206.   Index: LongInt;
  207.   P: PChar;
  208. begin
  209.   TheData[0] := #0;
  210.   GetField := TheData;
  211.   if Status <> 0 then Exit;
  212.   if (Rec < 1) or (Rec > NumRecords) then Exit;
  213.   if (Fld < 1) or (Fld > NumFields) then Exit;
  214.   Index := Rec * NumFields + Fld;
  215.   P := PCache(Cache)^.Get(Index);
  216.   if P = nil then
  217.   begin
  218.     if Rec <> CurRecord then
  219.     begin
  220.       CheckError(PXRecGoto(TblHandle, Rec));
  221.       CheckError(PXRecGet(TblHandle, RecHandle));
  222.       CurRecord := Rec;
  223.     end;
  224.     FillChar(TheData, SizeOf(TheData), ' ');
  225.     Tmp[0] := #0;
  226.     case FieldTypes^[Fld][0] of
  227.       'A':
  228.     CheckError(PXGetAlpha(RecHandle, Fld, SizeOf(Tmp), Tmp));
  229.       'N':
  230.     begin
  231.       CheckError(PXGetDoub(RecHandle, Fld, N));
  232.       if not IsBlankDouble(N) then
  233.         Str(N:12:4, Tmp);
  234.     end;
  235.       '$':
  236.     begin
  237.       CheckError(PXGetDoub(RecHandle, Fld, N));
  238.       if not IsBlankDouble(N) then
  239.         Str(N:12:2, Tmp);
  240.     end;
  241.       'S':
  242.     begin
  243.       CheckError(PXGetShort(RecHandle, Fld, I));
  244.       if not IsBlankShort(i) then
  245.         Str(I:6, Tmp)
  246.     end;
  247.       'D':
  248.     begin
  249.       CheckError(PXGetDate(RecHandle, Fld, L));
  250.       if Not IsBlankDate(L) then
  251.       begin
  252.         CheckError(PXDateDecode(L, ArgList[0], ArgList[1], ArgList[2]));
  253.         wvSprintf(Tmp, '%2d/%2d/%4d', ArgList);
  254.       end;
  255.     end;
  256.     end;
  257.     StrMove(TheData, Tmp, StrLen(Tmp));
  258.     TheData[FieldWidth(Fld)] := #0;
  259.     PCache(Cache)^.Add(Index, StrNew(TheData));
  260.   end
  261.   else
  262.     GetField := P;
  263. end;
  264.  
  265. function TPXTable.NumRecords: LongInt;
  266. begin
  267.   NumRecords := NumRecs;
  268. end;
  269.  
  270. function TPXTable.NumFields: Integer;
  271. begin
  272.   NumFields := NumFlds;
  273. end;
  274.  
  275. procedure TPXTable.PXError(Error: Integer);
  276. begin
  277.   MessageBox(GetFocus, PXErrMsg(Error), 'PXAccess', mb_OK)
  278. end;
  279.  
  280. end.
  281.